home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HyperLib 1997 Winter - Disc 1
/
HYPERLIB-1997-Winter-CD1.ISO.7z
/
HYPERLIB-1997-Winter-CD1.ISO
/
オンラインウェア
/
PRG
/
AEGetIcon sample.sit
/
AEGetIcon sample
/
AEGetIcon.c
next >
Wrap
Text File
|
1996-06-23
|
10KB
|
317 lines
/*
*--------------------------------------------------------------
* AEGetIcon.c
*--------------------------------------------------------------
* Most of source codes in this file come from FinderDrag
* written by Nitin Ganatra -- MacDTS, Apple Computer.
* However, the author fully rewrite the source codes to make
* it easier to incorporate my programs.
*--------------------------------------------------------------
* This code requires Scriptable Finder (System 7.5 or greater)
*--------------------------------------------------------------
*/
#include <AppleEvents.h>
#include <AERegistry.h>
#include <AEPackObject.h>
#include <Finder.h>
#include <Icons.h>
/* Finder specific constant definitions */
#define kFinderSignature 'MACS' /* signature */
#define pIconBitmap 'iimg' /* icon bitmap property */
#define formAlias typeAlias /* key desctopr of alias */
/*
*--------------------------------------------------------------
* function prototype to be included in some appropriate header
*--------------------------------------------------------------
*/
extern OSErr GetIconSuiteFromFinder(FSSpecPtr hfsObj, Handle *suite);
/*
*--------------------------------------------------------------
* static function prototypes
*--------------------------------------------------------------
*/
static OSErr AskForPropertyToFinder(FSSpecPtr hfs, const DescType prop, AppleEvent *reply);
static OSErr MakeSpecifierForFile(FSSpecPtr hfs, AEDesc *file);
static OSErr MakePropertySpecifierForSpecifier(DescType prop, AEDesc *spec, AEDesc *propSpec);
static OSErr GetAliasDesc(const FSSpecPtr hfs, AEDesc *aliasDesc);
static Size GetSizeFromIconType(DescType iconType);
static OSErr BuildIconSuiteFromAEDesc(Handle *suite, AEDesc *family);
/*
*--------------------------------------------------------------
* GetIconSuiteFromFinder
*--------------------------------------------------------------
* Get an icon suite from the desktop data base using AppleEvent.
* Given handle should be invalid.
*--------------------------------------------------------------
*/
OSErr GetIconSuiteFromFinder(FSSpecPtr theHFSObj, Handle *iconSuite)
{
AppleEvent replyEvent = { typeNull, nil };
AEDesc iconFamily = { typeNull, nil };
OSErr result;
/* Set up our locals for easy cleanup */
*iconSuite = nil;
result = AskForPropertyToFinder(theHFSObj, pIconBitmap, &replyEvent);
if (result == noErr) {
/* If not, get the icon family and build an icon suite */
result = AEGetParamDesc(&replyEvent, keyDirectObject, typeWildCard, &iconFamily);
if (result == noErr) {
result = BuildIconSuiteFromAEDesc(iconSuite, &iconFamily);
}
}
/* clean up descriptors */
(void)AEDisposeDesc(&iconFamily);
(void)AEDisposeDesc(&replyEvent);
return (result);
}
/*
*--------------------------------------------------------------
* AskForPropertyToFinder
*--------------------------------------------------------------
* request a files object's property to finder
*--------------------------------------------------------------
*/
static OSErr AskForPropertyToFinder(
FSSpecPtr theSpec,
const DescType theProperty,
AppleEvent * theAEReply)
{
AppleEvent finderEvent = { typeNull, nil };
AEDesc finderTarget = { typeNull, nil };
AEDesc fileSpecifier = { typeNull, nil };
AEDesc propertySpecifier = { typeNull, nil };
DescType finderSign;
OSErr result;
finderSign = kFinderSignature;
result = AECreateDesc(typeApplSignature, &finderSign,
sizeof(DescType), &finderTarget);
/* make an AppleEvent */
if (result == noErr) {
result = AECreateAppleEvent(kAECoreSuite, kAEGetData, &finderTarget,
kAutoGenerateReturnID, kAnyTransactionID, &finderEvent);
(void)AEDisposeDesc(&finderTarget);
}
/* make an object specifier for the interesting file */
if (result == noErr) {
result = MakeSpecifierForFile(theSpec, &fileSpecifier);
}
/* make an icon family property specifier for the file */
if (result == noErr) {
result = MakePropertySpecifierForSpecifier(
theProperty, &fileSpecifier, &propertySpecifier);
(void)AEDisposeDesc(&fileSpecifier);
}
/* stuff the icon family property specifier into the AppleEvent */
if (result == noErr) {
result = AEPutParamDesc(&finderEvent, keyDirectObject, &propertySpecifier);
(void)AEDisposeDesc(&propertySpecifier);
}
/* now send the requiest AppleEvent to the Finder */
if (result == noErr) {
result = AESend(&finderEvent, theAEReply,
kAEWaitReply + kAECanInteract + kAECanSwitchLayer,
kAENormalPriority, kAEDefaultTimeout, nil, nil);
(void)AEDisposeDesc(&finderEvent);
}
/* Finder may have sent us an resultor number */
if (result == noErr) {
DescType returnType;
Size returnSize;
long returnLong;
result = AEGetParamPtr(theAEReply, keyErrorNumber, typeLongInteger,
&returnType, &returnLong, sizeof(long), &returnSize);
if (result == noErr) {
result = (OSErr)returnLong;
} else {
result = noErr;
}
}
return (result);
}
/*
*--------------------------------------------------------------
* MakeSpecifierForFile
*--------------------------------------------------------------
* make the object specifier
*--------------------------------------------------------------
*/
static OSErr MakeSpecifierForFile(FSSpecPtr theHFSObj, AEDesc *fileSpecifier)
{
AEDesc hfsDesc = { typeNull, nil };
OSErr result;
/* create the file descriptor with the FSSpec passed in. */
result = GetAliasDesc(theHFSObj, &hfsDesc);
/* make the object specifier with a null container
(i.e., "file of <null>", or just "file") */
if (result == noErr) {
AEDesc nullDesc = { typeNull, nil };
result = CreateObjSpecifier(typeWildCard, &nullDesc,
formAlias, &hfsDesc, false, fileSpecifier);
(void)AEDisposeDesc(&hfsDesc);
}
return(result);
}
/*
*--------------------------------------------------------------
* MakePropertySpecifierForSpecifier
*--------------------------------------------------------------
* create a property specifier for the object specifier
*--------------------------------------------------------------
*/
static OSErr MakePropertySpecifierForSpecifier(DescType theProperty,
AEDesc *ofSpecifier, AEDesc *propertySpecifier)
{
AEDesc keyData = { typeNull, nil };
OSErr result;
/* Create a 'type' AEDesc with the desired property */
result = AECreateDesc(typeType, &theProperty, sizeof(DescType), &keyData);
/* With it create a property specifier for the object specifier passed to us */
if (result == noErr) {
result = CreateObjSpecifier(cProperty, ofSpecifier,
formPropertyID, &keyData, false, propertySpecifier);
(void)AEDisposeDesc(&keyData);
}
return result;
}
/*
*--------------------------------------------------------------
* GetAliasDesc
*--------------------------------------------------------------
* returns alias descriptor of the HFS object
*--------------------------------------------------------------
*/
static OSErr GetAliasDesc(const FSSpecPtr theSpec, AEDesc *theAliasDesc)
{
AliasHandle anAlias = nil;
OSErr result;
/* create an alias record of the target HFS object */
result = NewAlias(nil, theSpec, &anAlias);
/* create a list element of the target HFS object */
if (result == noErr) {
HLock((Handle)anAlias);
result = AECreateDesc(typeAlias, *anAlias, GetHandleSize((Handle)anAlias), theAliasDesc);
DisposeHandle((Handle)anAlias);
}
return(result);
}
/*
*--------------------------------------------------------------
* BuildIconSuiteFromAEDesc
*--------------------------------------------------------------
* this uses the Apple Event Manager to pick the icon data
* out of the 'ifam' AEDesc
*--------------------------------------------------------------
*/
static OSErr BuildIconSuiteFromAEDesc(Handle *iconSuite, AEDesc *iconFam)
{
AERecord anAERec = { typeNull, nil };
Ptr iconBff = nil;
DescType typeArray[6] = {
large1BitMask, large4BitData, large8BitData,
small1BitMask, small4BitData, small8BitData
};
Boolean maskAdded = false;
OSErr result;
/* allocate working buffer */
iconBff = NewPtr(kLarge8BitIconSize);
result = MemError();
/* create a new icon suite */
if (result == noErr) {
result = NewIconSuite(iconSuite);
}
/* coerce the icon desctiptor to desctiptor record so that
we can pick up the icon data using AEKeyword */
if (result == noErr) {
result = AECoerceDesc(iconFam, typeAERecord, (AEDesc *)&anAERec);
}
/* now pick up each icon family */
if (result == noErr) {
int familyCount;
for (familyCount = 0; familyCount < 6; familyCount ++) {
/* loop through the suite and grab the data from the AERecord for
each type of icon we're interested in. */
DescType iconType, typeCode;
Size iconSize;
iconType = typeArray[familyCount];
result = AEGetKeyPtr(&anAERec, iconType, iconType, &typeCode,
iconBff, kLarge8BitIconSize, &iconSize);
if (result == noErr) {
/* We don't set the error code for this unless the NewHandle
call fails, because it's possible that the 'ifam' doesn't
have an icon for one that we're interested in. */
Handle anIcon = NewHandle(iconSize);
if (anIcon != nil) {
/* OK, the memory alloc succeeded and we have data. Copy
it into the allocated icon and add it to the suite.
Set atLeastOne to true, to indicate later that we did
in fact add at least one icon to this suite. */
BlockMoveData(iconBff, *anIcon, iconSize);
result = AddIconToSuite(anIcon, *iconSuite, iconType);
if (result == noErr) {
if (iconType == large1BitMask) {
maskAdded = true;
}
}
} else {
result = MemError();
}
}
}
(void)AEDisposeDesc(&anAERec);
}
if (maskAdded && (result == errAEDescNotFound)) {
/* this means some of family members were
not found but the suite is still valid */
result = noErr;
}
else if (result != noErr) {
/* There was either an error in a memory allocation, or something
else went wrong (like no mask was added to the suite).
Get rid of the partially created suite. */
if (*iconSuite != nil) {
DisposeIconSuite(*iconSuite, true);
*iconSuite = nil;
}
}
if (iconBff != nil) {
DisposePtr(iconBff);
}
return (result);
}